package com.ruoyi.system.kysh.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.system.kysh.entity.*;
import com.ruoyi.system.kysh.entity.dto.DailyInfDto;
import com.ruoyi.system.kysh.entity.dto.TaskPlanAddDateDto;
import com.ruoyi.system.kysh.entity.dto.TaskPlanDateDto;
import com.ruoyi.system.kysh.entity.dto.TaskPlanDto;
import com.ruoyi.system.kysh.mapper.AcceptInfMapper;
import com.ruoyi.system.kysh.mapper.TaskPlanMapper;
import com.ruoyi.system.kysh.mapper.TeamClassInfMapper;
import com.ruoyi.system.kysh.service.*;
import com.ruoyi.system.kysh.utils.MyTimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class TaskPlanServiceImpl implements TaskPlanService {

    @Autowired
    private TaskPlanMapper taskPlanMapper;

    @Autowired
    private TeamClassInfMapper teamClassInfMapper;

    @Autowired
    private TeamClassInfService teamClassInfService;

    @Autowired
    private DrillInfService drillInfService;

    @Autowired
    private BorerInfService borerInfService;

    @Autowired
    private AcceptInfMapper acceptInfMapper;

    @Override
    public TaskPlanDateDto selectByTaskIdAndTaskName(String ticketNum, String ticketName, int page, int pageSize) {
        int firstIndex=(page-1)*pageSize;
        int endIndex=firstIndex+pageSize;
        List<TaskPlan> taskPlans = taskPlanMapper.selectByTaskIdAndTaskNameAll(ticketNum, ticketName);

        if(endIndex>taskPlans.size()){
            endIndex=taskPlans.size();
        }

        List<TaskPlan> taskPlans1 = taskPlans.subList(firstIndex, endIndex).stream().map(this::generateAllTaskPlan).collect(Collectors.toList());

        List<TaskPlanAddDateDto> taskPlanAddDateDtos=new ArrayList<>(taskPlans.size());
        taskPlans1.forEach(it->{
            TaskPlanAddDateDto taskPlanAddDateDto = new TaskPlanAddDateDto();
            taskPlanAddDateDto.setTaskPlan(it);
            taskPlanAddDateDto.setDate(MyTimeUtil.changeDateFormatToDay(it.getStartTime()));
            taskPlanAddDateDtos.add(taskPlanAddDateDto);
        });


        TaskPlanDateDto taskPlanDateDto = new TaskPlanDateDto();
        taskPlanDateDto.setTaskPlanAddDateDtos(taskPlanAddDateDtos);
        taskPlanDateDto.setSize(taskPlans1.size());
        taskPlanDateDto.setTotal(taskPlans.size());
        return taskPlanDateDto;
    }

    @Override
    public TaskPlan selectDetailByTicketNum(String ticketNum) {
        List<TaskPlan> taskPlans = taskPlanMapper.selectByTaskIdAndTaskName(ticketNum, null, 0, 10);
        if(taskPlans==null || taskPlans.isEmpty()){
            return null;
        }
        TaskPlan taskPlan = taskPlans.get(0);
        return generateAllTaskPlan(taskPlan);
    }

    @Override
    public boolean deleteByTicketNum(String ticketNum) {
        List<TaskPlan> taskPlans = taskPlanMapper.selectByTaskIdAndTaskName(ticketNum, null, 0, 10);
        if(taskPlans==null || taskPlans.isEmpty()){
            return false;
        }
        TaskPlan taskPlan = taskPlans.get(0);

        if(taskPlan.getStatus().equals("0")){
            taskPlanMapper.deleteTaskPlanById(taskPlan.getId());
            return true;
        }

        return false;
    }

    String generateTicketNum(TaskPlan taskPlan){
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd");
        String[] strings = simpleDateFormat.format(taskPlan.getStartTime()).split("-");
        String join = String.join("", new ArrayList<>(Arrays.asList(strings)));
        String substring = UUID.randomUUID().toString().replace("-", "").substring(0, 8);
        String taskSailing;
        if(taskPlan.getSailings().equals("八点班")){
            taskSailing="8";
        }else if (taskPlan.getSailings().equals("四点班")) {
            taskSailing="4";
        }else {
            taskSailing="0";
        }
        return substring+join+"-"+taskSailing;
    }

    String generateTicketName(TaskPlan taskPlan){
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd");
        String s=simpleDateFormat.format(taskPlan.getStartTime());
        return s+"作业工单-"+taskPlan.getSailings();
    }

    Date generateTime(TaskPlan taskPlan,String s){
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd");
        String date = simpleDateFormat.format(taskPlan.getStartTime());
        String time;
        switch (s) {
            case "0":
                time = " 00:00:00";
                break;
            case "8":
                time = " 08:00:00";
                break;
            case "4":
                time = " 16:00:00";
                break;
            default:
                time = " 23:59:59";
                break;
        }

        SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            return format.parse(date+time);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    void save(TaskPlan taskPlan){
        String ticketNum;
        //生成唯一工单编号
        while(true){
            ticketNum = generateTicketNum(taskPlan);
            Long id =taskPlanMapper.selectTaskIdByTicketNum(ticketNum);
            if(id==null){
                break;
            }
        }
        //生成工单名称
        String ticketName = generateTicketName(taskPlan);
        //生成开始/结束时间
        Date startTime;
        Date ddlTime;
        if(taskPlan.getSailings().equals("八点班")){
            startTime=generateTime(taskPlan,"8");
            ddlTime=generateTime(taskPlan,"4");
        }else if (taskPlan.getSailings().equals("四点班")) {
            startTime=generateTime(taskPlan,"4");
            ddlTime=generateTime(taskPlan,"-1");
        }else {
            startTime=generateTime(taskPlan,"0");
            ddlTime=generateTime(taskPlan,"8");
        }
        String status="0";

        taskPlan.setTicketNum(ticketNum);
        taskPlan.setTicketName(ticketName);
        taskPlan.setStartTime(startTime);
        taskPlan.setDdlTime(ddlTime);
        taskPlan.setStatus(status);
        taskPlan.setCreateTime(MyTimeUtil.nowTime());
        taskPlan.setUpdateTime(MyTimeUtil.nowTime());

        taskPlanMapper.saveTaskPlanTable(taskPlan);
        Long taskId=taskPlanMapper.selectTaskIdByTicketNum(taskPlan.getTicketNum());
        Long deptId = teamClassInfMapper.selectDeptIdByName(taskPlan.getDeptName(), taskPlan.getParentDeptName());
        taskPlanMapper.saveDeptIdBuTaskId(taskId,deptId);
        taskPlanMapper.saveDrillIdByTaskId(taskId,taskPlan.getBorerId());
        taskPlanMapper.saveBorerIdByTaskId(taskId,taskPlan.getBorerMachId());
    }

    void updateForDelTrue(TaskPlan taskPlan){
        Date startTime;
        Date ddlTime;
        if(taskPlan.getSailings().equals("八点班")){
            startTime=generateTime(taskPlan,"8");
            ddlTime=generateTime(taskPlan,"4");
        }else if (taskPlan.getSailings().equals("四点班")) {
            startTime=generateTime(taskPlan,"4");
            ddlTime=generateTime(taskPlan,"-1");
        }else {
            startTime=generateTime(taskPlan,"0");
            ddlTime=generateTime(taskPlan,"8");
        }
        taskPlan.setStartTime(startTime);
        taskPlan.setDdlTime(ddlTime);
        taskPlan.setUpdateTime(MyTimeUtil.nowTime());

        taskPlanMapper.updateTaskPlanTable(taskPlan);
        Long deptId = teamClassInfMapper.selectDeptIdByName(taskPlan.getDeptName(), taskPlan.getParentDeptName());
        taskPlanMapper.updateDeptIdBuTaskId(taskPlan.getId(), deptId);
        taskPlanMapper.updateDrillIdByTaskId(taskPlan.getId(), taskPlan.getBorerId());
        taskPlanMapper.updateBorerIdByTaskId(taskPlan.getId(), taskPlan.getBorerMachId());
    }

    @Override
    public boolean saveTaskPlan(TaskPlan taskPlan) {
        save(taskPlan);
        return true;
    }

    @Override
    public boolean updateTaskPlan(TaskPlan taskPlan) {
        TaskPlan task=taskPlanMapper.selectByIdNotSeeDel(taskPlan.getId());
        if(task!=null){
            if(task.getDeleteLogic().equals("0")){
                updateForDelTrue(taskPlan);
                return true;
            }
        }
        return false;
    }

    public TaskPlan generateAllTaskPlan(TaskPlan taskPlan){
        Long deptId = taskPlanMapper.selectDeptIdByTaskId(taskPlan.getId());
        String deptName = teamClassInfMapper.selectDeptNameByDeptId(deptId);
        String parentName = teamClassInfMapper
                .selectDeptNameByDeptId(teamClassInfMapper.selectParentIdByDeptId(deptId));
        String morName = teamClassInfService.findMorByDept(deptName, parentName);
        String acceptorName = teamClassInfService.findAccByDept(deptName, parentName);
        Long borerId = taskPlanMapper.selectBorerIdByTaskId(taskPlan.getId());

        LambdaQueryWrapper<DrillInf> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(DrillInf::getBorerId, borerId);
        DrillInf drillInf = drillInfService.getOne(lambdaQueryWrapper);

        String borerMachId=taskPlanMapper.selectMachIdByTaskId(taskPlan.getId());
        String borerNum=taskPlanMapper.selectBorerNumByMachId(borerMachId);

        taskPlan.setParentDeptName(parentName);
        taskPlan.setDeptName(deptName);
        taskPlan.setAcceptorName(acceptorName);
        taskPlan.setMorName(morName);
        taskPlan.setBorerId(borerId);
        taskPlan.setBorerLoc(drillInf.getBorerLoc());
        taskPlan.setBorerType(drillInf.getBorerType());
        taskPlan.setBorerNum(borerNum);
        taskPlan.setBorerMachId(borerMachId);
        return taskPlan;
    }

    @Override
    public TaskPlan selectByTaskId(Long id) {
        TaskPlan taskPlan = taskPlanMapper.selectByTaskId(id);
        if(taskPlan==null){
            return null;
        }
        return generateAllTaskPlan(taskPlan);
    }

    @Override
    public void updateTaskStatus(Long id, String status) {
        taskPlanMapper.updateSailingsByTaskId(id,status,new Date());
    }

    @Override
    public List<TaskPlan> selectByUserId(Long userId) {
        Long deptId=teamClassInfMapper.selectDeptIdByUserId(userId);
        List<Long> taskIds=taskPlanMapper.selectTaskIdByDeptId(deptId);
        List<TaskPlan> taskPlans=new ArrayList<>();
        taskIds.forEach((taskId)->{
            TaskPlan taskPlan = taskPlanMapper.selectByTaskId(taskId);
            if (taskPlan!=null&&taskPlan.getStatus().equals("1")) {
                taskPlans.add(generateAllTaskPlan(taskPlan));
            }
        });
        return taskPlans;
    }

    @Override
    public TaskPlanDto selectTaskInfDetailByTicketNum(String ticketNum) {
        List<TaskPlan> taskPlans = taskPlanMapper.selectByTaskIdAndTaskName(ticketNum, null, 0, 10);
        if(taskPlans==null || taskPlans.isEmpty()){
            return null;
        }
        TaskPlan taskPlan = taskPlans.get(0);
        Long deptId = taskPlanMapper.selectDeptIdByTaskId(taskPlan.getId());
        String deptName = teamClassInfMapper.selectDeptNameByDeptId(deptId);
        String parentName = teamClassInfMapper
                .selectDeptNameByDeptId(teamClassInfMapper.selectParentIdByDeptId(deptId));
        String morName = teamClassInfService.findMorByDept(deptName, parentName);
        String acceptorName = teamClassInfService.findAccByDept(deptName, parentName);

        Long borerId = taskPlanMapper.selectBorerIdByTaskId(taskPlan.getId());
        LambdaQueryWrapper<DrillInf> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(DrillInf::getBorerId, borerId);
        DrillInf drillInf = drillInfService.getOne(lambdaQueryWrapper);

        String borerMachId=taskPlanMapper.selectMachIdByTaskId(taskPlan.getId());
        LambdaQueryWrapper<BorerInf> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(BorerInf::getBorerId,borerMachId);
        BorerInf borerInf = borerInfService.getOne(queryWrapper);

        taskPlan.setParentDeptName(parentName);
        taskPlan.setDeptName(deptName);
        taskPlan.setAcceptorName(acceptorName);
        taskPlan.setMorName(morName);

        TaskPlanDto taskPlanDto=new TaskPlanDto();
        taskPlanDto.setTaskPlan(taskPlan);
        taskPlanDto.setDrillInf(drillInf);
        taskPlanDto.setBorerInf(borerInf);

        return taskPlanDto;
    }

    @Override
    public void bindVideoByTaskId(Long taskId, String videoLoc) {
        taskPlanMapper.bindVideoByTaskId(taskId,videoLoc);
    }

    @Override
    public TaskPlanDateDto selectDaily(Date workTime, String sailings,String acceptNum, int page, int pageSize) {
        int firstIndex=(page-1)*pageSize;
        int endIndex=firstIndex+pageSize;

        List<TaskPlan> taskPlans=taskPlanMapper.selectDailyByTimeAndSailingsAll(workTime,sailings,acceptNum);

        if(endIndex>taskPlans.size()){
            endIndex=taskPlans.size();
        }

        List<TaskPlan> taskPlans1 = taskPlans.subList(firstIndex, endIndex).stream().peek(this::generateAllTaskPlan).collect(Collectors.toList());

        List<TaskPlanAddDateDto> taskPlanAddDateDtos=new ArrayList<>(taskPlans.size());
        taskPlans1.forEach(it->{
            TaskPlanAddDateDto taskPlanAddDateDto = new TaskPlanAddDateDto();
            taskPlanAddDateDto.setTaskPlan(it);
            taskPlanAddDateDto.setDate(MyTimeUtil.changeDateFormatToDay(it.getStartTime()));
            taskPlanAddDateDtos.add(taskPlanAddDateDto);
        });

        TaskPlanDateDto taskPlanDateDto = new TaskPlanDateDto();

        taskPlanDateDto.setTaskPlanAddDateDtos(taskPlanAddDateDtos);
        taskPlanDateDto.setSize(taskPlans1.size());
        taskPlanDateDto.setTotal(taskPlans.size());

        return taskPlanDateDto;

    }

    public DailyInfDto selectDetailInf(Long taskId){
        DailyInfDto dailyInfDto=new DailyInfDto();

        TaskPlan taskPlan=generateAllTaskPlan(taskPlanMapper.selectByTaskId(taskId));

        Long borerId = taskPlanMapper.selectBorerIdByTaskId(taskId);
        LambdaQueryWrapper<DrillInf> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(DrillInf::getBorerId, borerId);
        DrillInf drillInf = drillInfService.getOne(lambdaQueryWrapper);

        String borerMachId=taskPlanMapper.selectMachIdByTaskId(taskId);
        LambdaQueryWrapper<BorerInf> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(BorerInf::getBorerId,borerMachId);
        BorerInf borerInf = borerInfService.getOne(queryWrapper);

        List<AcceptInf> acceptInf=acceptInfMapper.selectInfByTaskId(taskId);

        AIInf aiInf=acceptInfMapper.selectAIInfByAcceptBindLoc(acceptInf.get(0).getBindVideo());

        dailyInfDto.setTaskPlan(taskPlan);
        dailyInfDto.setDrillInf(drillInf);
        dailyInfDto.setBorerInf(borerInf);
        dailyInfDto.setAcceptInf(acceptInf.get(0));

        if(aiInf!=null){
            aiInf.setTotalTime((aiInf.getDdlTime().getTime()-aiInf.getStartTime().getTime())/(1000.0*60));
        }
        dailyInfDto.setAiInf(aiInf);

        return dailyInfDto;
    }

    @Override
    public List<TaskPlan> selectListByUserId(Long userId) {
        Long deptId=teamClassInfMapper.selectDeptIdByUserId(userId);
        List<Long> taskIds=taskPlanMapper.selectTaskIdByDeptId(deptId);
        List<TaskPlan> taskPlans=new ArrayList<>();
        taskIds.forEach((taskId)->{
            TaskPlan taskPlan = taskPlanMapper.selectByTaskId(taskId);
            if (taskPlan!=null&&!taskPlan.getStatus().equals("0")) {
                taskPlans.add(generateAllTaskPlan(taskPlan));
            }
        });
        return taskPlans;

    }

    @Override
    public void changeTaskStatus(Long taskId, String status) {
        taskPlanMapper.changeTaskStatus(taskId,status);
    }

    @Override
    public List<DailyInfDto> selectDetailDailyInf(Date date) {

        List<DailyInfDto> dailyInfDtos=new ArrayList<>();

        List<Long> taskIds=taskPlanMapper.selectTaskIdByDate(date);

        if(taskIds==null||"".equals(taskIds.toString())){
            return null;
        }

        taskIds.forEach(taskId->{
            dailyInfDtos.add(selectDetailInf(taskId));
        });

        return dailyInfDtos;

    }

    @Override
    public DailyInfDto selectDetailDailyInfToAccept(Long taskId) {
        DailyInfDto dailyInfDto = selectDetailInf(taskId);
        List<String> workers=taskPlanMapper.selectWorkersByTaskId(taskId);
        StringBuffer stringBuffer=new StringBuffer();
        workers.forEach(worker->{
            stringBuffer.append(worker);
            stringBuffer.append(",");
        });
        if (stringBuffer.length()>0) {
            stringBuffer.deleteCharAt(stringBuffer.length()-1);
        }
        dailyInfDto.setWorker(stringBuffer.toString());
        return dailyInfDto;

    }

    @Override
    public boolean saveTaskPlanWithIssued(TaskPlan taskPlan) {
        saveAndIssued(taskPlan);
        return true;
    }

    private void saveAndIssued(TaskPlan taskPlan) {
        String ticketNum;
        //生成唯一工单编号
        while(true){
            ticketNum = generateTicketNum(taskPlan);
            Long id =taskPlanMapper.selectTaskIdByTicketNum(ticketNum);
            if(id==null){
                break;
            }
        }
        //生成工单名称
        String ticketName = generateTicketName(taskPlan);
        //生成开始/结束时间
        Date startTime;
        Date ddlTime;
        if(taskPlan.getSailings().equals("八点班")){
            startTime=generateTime(taskPlan,"8");
            ddlTime=generateTime(taskPlan,"4");
        }else if (taskPlan.getSailings().equals("四点班")) {
            startTime=generateTime(taskPlan,"4");
            ddlTime=generateTime(taskPlan,"-1");
        }else {
            startTime=generateTime(taskPlan,"0");
            ddlTime=generateTime(taskPlan,"8");
        }
        taskPlan.setTicketNum(ticketNum);
        taskPlan.setTicketName(ticketName);
        taskPlan.setStartTime(startTime);
        taskPlan.setDdlTime(ddlTime);
        taskPlan.setStatus("1");
        taskPlan.setCreateTime(MyTimeUtil.nowTime());
        taskPlan.setUpdateTime(MyTimeUtil.nowTime());

        taskPlanMapper.saveTaskPlanTable(taskPlan);
        Long taskId=taskPlanMapper.selectTaskIdByTicketNum(taskPlan.getTicketNum());
        Long deptId = teamClassInfMapper.selectDeptIdByName(taskPlan.getDeptName(), taskPlan.getParentDeptName());
        taskPlanMapper.saveDeptIdBuTaskId(taskId,deptId);
        taskPlanMapper.saveDrillIdByTaskId(taskId,taskPlan.getBorerId());
        taskPlanMapper.saveBorerIdByTaskId(taskId,taskPlan.getBorerMachId());
    }
}
